<script setup>
import FormBox from "../FormBox.vue";
import {ref} from "vue";
import DocumentResultTitle from "./document/DocumentResultTitle.vue";
import DocumentResultContent from "./document/DocumentResultContent.vue";
import FetchUtil from "../../libs/FetchUtil.js";
import api from "../../libs/api.js";

const props = defineProps({
  agent: {
    type: Object,
    required: true,
    default: () => ({
      id: null,
      name: '',
      agentType: '',
      note: '',
      icon: ''
    })
  }
});

const form = ref({
  template: '',
  templateName: '',
  reference: '',
  referenceName: '',
  extraRequirements: ''
});
const submitData = new FormData();
const uploadTemplate = () => {
  // 模拟上传模板
  uploadFile(['.md', '.txt', '.docx', 'doc', '.pdf']).then(file => {
    if (file) {
      form.value.template = file.name;
      form.value.templateName = file.name;
      submitData.set('template', file);
    }
  });
};
const uploadReference = () => {
  // 模拟上传参考文件
  uploadFile(['.md', '.txt', '.docx', 'doc', '.pdf']).then(file => {
    if (file) {
      form.value.reference = file.name;
      form.value.referenceName = file.name;
      submitData.set('reference', file);
    }
  });
};

const uploadFile = (types) => {
  let input = document.createElement('input');
  input.type = 'file';
  input.accept = types.join(',');
  return new Promise((resolve, reject) => {
    input.onchange = (e) => {
      const file = e.target.files[0];
      if (file) {
        resolve(file);
      } else {
        reject('No file selected');
      }
    };
    input.click();
  });
}
const finish = ref(false)
const titleList = ref([])
const selectedTitle = ref(null);
const onSelectTitle = (title) => {
  selectedTitle.value = title;
  console.log('选中标题:', title);
};

let token = localStorage.getItem('global_token');
if (!token) {
  alert('请先登录');
}else{
  token = JSON.parse(token).token;
}
const running = ref(false);
const startGenerating = () => {
  if (running.value){
    return
  }
  submitData.set('extraRequirements', form.value.extraRequirements);
  if (submitData.get('template') && submitData.get('reference')) {
    running.value = true;
    console.log('开始生成文档', submitData);
    fetch(`/api/v1/agent/${props.agent.id}/document/generate`, {
      method: 'POST',
      body: submitData,
      headers: {
        'Authorization': `Bearer ${token}`
      },
    }).then(response => {
      const reader = response.body.getReader();
      const decoder = new TextDecoder('utf-8');
      return reader.read().then(function processText({ done, value }) {
        if (done) {
          running.value = false
          console.log('Stream finished');
          finish.value = true;
          return;
        }
        let allLine = decoder.decode(value);
        let lines = [allLine]
        if (allLine.concat('\n')){
          lines = allLine.split('\n');
        }
        for(let i in lines){
          let line = lines[i].trim();
          if (line === ''){
            continue;
          }
          if (line === '[DONE]'){
            return reader.read().then(processText);
          }
          if (line.startsWith("data:")){
            line = line.substring(5);
          }
          try {
            const json = JSON.parse(line);
            if(json.titles && json.titles.length > 0){
              titleList.value = json.titles.map(title => ({
                title: title.title,
                requirements: title.requirements || '',
                content: title.content || '',
                children: title.children || [],
                status: 'waiting' // 假设所有标题都已完成
              }));
            }
            if(json.content && (json.content.text || json.content.complete)){
              // 处理内容
              const content = json.content.text;
              const title = json.content.title;
              const generatingTitle = selectTitleByTitleText(titleList.value, title);
              if (generatingTitle) {
                if (!generatingTitle.content){
                  generatingTitle.content = '';
                }
                generatingTitle.content += content;
                if (json.content.complete){
                  console.log('内容生成完成:', title);
                  generatingTitle.status = 'completed'; // 如果内容生成完成，更新状态
                } else {
                  generatingTitle.status = 'generating'; // 如果内容还在生成中，保持状态为生成中
                }
              } else {
                console.warn('未找到标题:', title);
              }
            }
            if (selectedTitle.value){
              selectedTitle.value = selectTitleByTitleText(titleList.value, selectedTitle.value.title) || null;
            } else {
              selectedTitle.value = titleList.value[0] || null;
            }
          }catch (e){
            console.error('Error parsing JSON:', e, 'Line:', line);
            // 如果解析失败，可能是因为数据格式不正确或流中包含非JSON数据
            // 可以选择忽略此行或记录错误
            // alert('发生错误, 请尝试重新查询');
          }
        }
        // Util.setLocalStorage("message_list_" + props.chat.id, messages.value)
        return reader.read().then(processText);
      });
    }).catch(error => {
      running.value = false
      console.error('文档生成失败', error);
    });
  } else {
    alert('请上传大纲模板和参考文件');
  }
};
const selectTitleByTitleText = (titles, title) => {
  if (!title || !titles || titles.length === 0) {
    return null;
  }
  for (let i = 0; i < titles.length; i++) {
    const item = titles[i];
    if (item.title === title) {
      return item;
    }
    if (item.children && item.children.length > 0) {
      const child = selectTitleByTitleText(item.children, title);
      if (child) {
        return child;
      }
    }
  }
  return null;
}

const onEdieContent = (title, requirements) => {
  console.log('编辑内容:', title, '要求:', requirements);
  // const req = {
  //   titles: titleList.value,
  //   title: title,
  //   requirements: requirements
  // };
  const request = new FormData();
  request.set('titles', JSON.stringify(titleList.value));
  request.set('title', JSON.stringify(title));
  request.set('requirements', requirements);
  request.set('template', submitData.get('template'));
  request.set('reference', submitData.get('reference'));
  request.set('extraRequirements', form.value.extraRequirements);
  title.content = ''; // 清空内容，准备重新生成
  FetchUtil.jsonStream(`/api/v1/agent/${props.agent.id}/document/edit`, {
    method: 'POST',
    body: request,
  }, (done, data) => {
    if (done) {
      console.log('编辑完成');
    }
    console.log(data)
    if(data && data.content){
      title.content += data.content.text || '';
    }
  })
};
const downloadDocument = () => {
  api.post(`/api/v1/agent/${props.agent.id}/document/download`, titleList.value, {
    responseType: 'blob',
  }).then(response => {
    const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' });
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'document.docx';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    window.URL.revokeObjectURL(url);
  }).catch(error => {
    console.error('下载文档失败', error);
  });
}
</script>

<template>
  <div class="document-agent">
    <div class="agent-header">
      <img :src="agent.icon" alt="Agent Icon" class="agent-icon">
      <div class="agent-info">
        <div class="agent-name">{{ agent.name }}</div>
        <div class="agent-note">{{ agent.note }}</div>
      </div>
    </div>
    <div class="agent-workspace">
      <div class="query-box">
        <form-box title="生成条件">
          <div class="form-items">
            <div class="form-item-inline">
              <label>大纲模板：</label>
              <div class="form-item-input-upload">
                <div class="form-item-input-upload-display" :class="{'empty-file': !form.templateName}">{{form.templateName || '请上传大纲模板'}}</div>
                <div class="form-item-input-upload-button" @click="uploadTemplate">上传</div>
              </div>
            </div>
            <div class="form-item-inline">
              <label>参考文件：</label>
              <div class="form-item-input-upload">
                <div class="form-item-input-upload-display" :class="{'empty-file': !form.referenceName}">{{form.referenceName || '请上传参考文件'}}</div>
                <div class="form-item-input-upload-button" @click="uploadReference">上传</div>
              </div>
            </div>
          </div>
          <div class="form-items">
            <div class="form-item">
              <div class="label">额外要求：</div>
              <div class="form-item-input-textarea">
                <textarea v-model="form.extraRequirements" placeholder="请输入额外要求"></textarea>
                <div class="submit" @click="startGenerating" :class="{disable: running}">开始生成</div>
              </div>
            </div>
          </div>
        </form-box>
      </div>
      <div class="result-box">
        <form-box title="生成结果" style="height: calc(100vh - 400px);">
          <div class="result-content">
            <div class="result-left-navs">
              <document-result-title v-for="title in titleList" :key="title" :title="title" :on-select="onSelectTitle" :selected="selectedTitle"/>
            </div>
            <div class="result-right-content">
              <document-result-content :title="selectedTitle" v-if="selectedTitle" :key="selectedTitle" :on-edit="onEdieContent"/>
            </div>
          </div>
        </form-box>
      </div>
    </div>
    <div class="download-btn" v-if="finish" @click="downloadDocument">
      <img src="../../assets/icons/download-doc.svg"  alt="下载文档"/>
    </div>
  </div>
</template>

<style scoped lang="less">
.document-agent {
  display: flex;
  flex-direction: column;
  height: 100%;
  background-color: #fff;

  .agent-header {
    display: flex;
    align-items: center;
    padding: 10px;
    border-bottom: 1px solid #e4e4e4;

    .agent-icon {
      width: 50px;
      height: 50px;
      border-radius: 50%;
      margin-right: 15px;
    }

    .agent-info {
      .agent-name {
        font-size: 20px;
        font-weight: bold;
        color: #333;
      }
      .agent-note {
        font-size: 14px;
        color: #666;
      }
    }
  }

  .agent-workspace {
    flex: 1;
    padding: 20px;
    display: flex;
    flex-direction: column;

    .query-box {
      display: flex;
      flex-direction: column;

      .form-items{
        display: flex;
        flex-direction: row;
        gap: 20px;
        width: 100%;

        .form-item-inline {
          display: flex;
          align-items: center;

          label {
            width: 80px;
            font-weight: bold;
          }

          .form-item-input-upload {
            display: flex;
            align-items: center;
            border: 1px solid #e4e4e4;
            border-radius: 5px;
            background-color: #f9f9f9;
            min-width: 300px;
            flex-direction: row;
            justify-content: space-between;

            .form-item-input-upload-display {
              flex-grow: 1;
              max-width: 230px;
              overflow: hidden;
              text-overflow: ellipsis;
              white-space: nowrap;
              padding-left: 10px;
              padding-right: 10px;

              &.empty-file{
                color: #999;
              }
            }

            .form-item-input-upload-button {
              padding: 5px 10px;
              background-color: #007bff;
              color: #fff;
              border-radius: 5px;
              cursor: pointer;

              &:hover {
                background-color: #0056b3;
              }
            }
          }


        }

        .form-item{
          display: flex;
          flex-direction: row;
          margin-top: 10px;
          width: 100%;

          .label {
            font-weight: bold;
            margin-bottom: 5px;
          }

          .form-item-input-textarea {
            position: relative;
            border: 1px solid #e4e4e4;
            flex: 1;
            border-radius: 5px;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            padding: 10px;
            // 输入框被选中时, 边框颜色变为蓝色
            &:focus-within {
              border-color: #007bff;
            }
            textarea {
              width: calc(100% - 10px);
              height: 70px;
              border: none;
              resize: none;
              margin-bottom: 50px;
              outline: none;
            }

            .submit {
              position: absolute;
              right: 10px;
              bottom: 10px;
              padding: 5px 15px;
              background-color: #007bff;
              color: #fff;
              border-radius: 5px;
              cursor: pointer;
              &.disable {
                background-color: #ccc;
                cursor: not-allowed;
              }

              &:hover {
                background-color: #0056b3;
              }
            }
          }
        }
      }
    }

    .result-box {
      flex: 1;
      margin-top: 20px;
      /deep/.form-box{
        height: 100%;
      }

      .result-content {
        display: flex;
        height: 100%;

        .result-left-navs {
          width: 250px;
          border: 1px solid #e4e4e4;
          padding: 10px 10px 10px 0;
          overflow-y: auto;
        }

        .result-right-content {
          flex: 1;
          padding-left: 10px;
          overflow-y: auto;
        }
      }
    }
  }

  .download-btn{
    // 右下角圆圈浮动
    position: fixed;
    bottom: 50px;
    right: 50px;
    width: 50px;
    height: 50px;
    background-color: white;
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);

    // 入场动画, 从屏幕中间由大到小到右下角, 曲线动画, 由快到慢
    animation: zoomIn 1s cubic-bezier(0.882, 0.014, 0.182, 0.995);

    @keyframes zoomIn {
      from {
        transform: scale(15);
        // 从中间
        right: 50%;
        bottom: 50%;
      }
      to {
        transform: scale(1);
        // 到右下角
        right: 50px;
        bottom: 50px;
      }
    }

    img {
      width: 24px;
      height: 24px;
    }
  }
}
</style>
